<?php
/**
 * $Id: form.php 1178 2014-07-25 10:55:52Z shrey $
 * 
 * Extended Form helper for quick implementations of common tasks like AJAX forms, JS validation, Captcha etc.
 * 
 * Copyright 2005 - 2008, Giga Promoters
 * 						  608 Aggarwal Cyber Plaza
 *						  Netaji Subhash Place, Delhi - 110034
 *						  www.gigapromoters.com
 * 
 *
 * @version 			$Rev: 1178 $
 * @lastModifiedBy		$LastChangedBy: shrey $
 * @lastChanged			$Date: 2014-07-25 16:25:52 +0530 (Fri, 25 Jul 2014) $
 * @copyright 			Giga Promoters (www.gigapromoters.com)
 * 
 */

App::import('Helper','BaseForm');
require_once(LIBS.'view'.DS.'helpers'.DS.'base_form.php');

class FormHelper extends BaseFormHelper {
	
	var $helpers = array('Html', 'Session', 'Javascript');
	var $ajaxForm;
	var $toolTipAdded = false; 
	
	var $toolTipStyle = 'cream';
	var $toolTipType = 'qtip';
	var $disableDiv = false;
	var $hasFormError = false;
	
	var $ratingFn = 'typeRating';
	
	function error($field, $text = null, $options = array()) 
	{
		$return = parent::error($field, $text, $options);
		if(!is_null($return))
		{
			// check if its flash only request
			if(isset($this->params['isAjax']) && $this->params['isAjax']==1 && isset($_GET['flashOnly']))
			{
				//$fieldName = $model.".".$field;
				$domId = $this->domId($field);
				// append js error
				$return .= $this->Javascript->startup('invalidateField("'.$domId.'", \''.$return.'\');');
			}
			$this->hasFormError = true;
		}
		return $return;
	}
	
	/**
	 * Available $options =>
	 * 'ajax': If sets to true, Converts the form into the AJAX form. Alerts response/flash message in JS alert box.
	 *         If 'response' option is set to 'inline'. Flash message will appear inline DOM with animation
	 * 
	 * 'js_validate': If sets to true, form will be validated by Javascript automatically.    
	 *
	 * @param unknown_type $model
	 * @param unknown_type $options
	 * @return unknown
	 */
	function create($model = null, $options = array())
	{
		if(isset($this->params['isAjax']) && $this->params['isAjax']==1 && !isset($options['ajax']))
		{
			$options['ajax'] = array(); // auto-convert to ajax when ajax is used
		}

		$output = "";
		//if(isset($options['animate']))
		if(isset($options['ajax']) && is_array($options['ajax']))
		{
			if(!isset($options['id']))
			{
				$options['id'] = 'form' . intval(mt_rand());
			}
			// @deprecated to GigaAjaxForm js
			//$this->Javascript->startup('GigaAjaxForm.init(\''.$options['id'].'\');');
			
			//a form input to notify systme that is a ajax request in case iframe is used in ajax.
			/*
			$ajaxFlag = $this->hidden('_isAjax', array('name' => '_isAjax', 'value' => 1, 'id' => null));
			$output = $ajaxFlag.$output;*/
		}
		
		// js validation code
		if(isset($options['js_validate']) && $options['js_validate']=='true')
		{
			if(!isset($options['id']))
			{
				$options['id'] = 'form' . intval(mt_rand());
			}
			$this->Javascript->link('/cms/js/jquery.validate.min.js',false);
			$hackyJs = '$("#'.$options['id'].' div.required input").addClass("required");';
			$output .= '<script>$(document).ready(function() { '.$hackyJs.'$("#'.$options['id'].'").validate(); }); </script>';
			unset($options['js_validate']);
		}

		
		// unset js options
		$output = parent::create($model, $options).$output;
		return $output;
	}
	
	/**
	 * Helps generating AJAX forms if $this->ajaxForm is set.
	 *
	 * @param unknown_type $caption
	 * @param unknown_type $options
	 * @return unknown
	 */
	function submit($caption = null, $options = array())
	{
		$output = '';
		$output .= parent::submit($caption, $options);
		if(isset($this->ajaxForm))
		{
			$output .= "<div class='form_progress' style='display: none;'></div>";
			unset($this->ajaxForm);
		}
		return $output;
	}
	
	function _getCurrentModel()
	{
		$model = ClassRegistry :: getObject($this->model());
		if(strpos($this->currentField, '.'))
		{
			$modelAlias = Utility::getModelName($this->currentField);
			if($modelAlias)
				$model = ClassRegistry :: getObject($modelAlias);
				
			/* @todo Dont call a model by hit and run now, table might not be existing. See admin login file for example.
			Not sure if above comment is still valid
			if(!is_object($model))
			{
				$model = Utility::getModelObject($modelAlias);
			}*/
				
			$parts = explode('.', $this->currentField);
			$count = count($parts);
			//pr($parts);
			if($count == 4) // this is a hack for setting models for parent field type
			{
				$field = $parts[1];
				$model1 = $parts[0];
				$childModel = Utility::getModelObject($model1)->getFieldProperty($field, 'childInfo');
				if(isset($childModel['model']))
					$model = cri($childModel['model']);
			}
		}
		return $model;
	}
	
	function _setDefaultOptions()
	{
		$model = $this->_getCurrentModel();
		
		// fetch default form options from model
		if($model && is_array($fieldOptions = $model->getFieldProperties($this->currentField)))
		{
			if(isset($this->appenModelName) && $this->appenModelName==true)
				$this->currentField = $model->alias.'.'.$this->currentField;
			if(!empty($this->options))
				$this->options = am($fieldOptions, $this->options);
			else
				$this->options = $fieldOptions;
		}
		
		
		// hack to populate options for child fields by default
		/*
		$field = $this->currentField;
		if(strpos($this->currentField, '.'))
		{
			$field = end(explode('.', $this->currentField));
			if(in_array($field, $this->childFields))
			{
				
			}
		}*/
	}
	
	/* Needs some serious refactoring - currently disabled
	function children()
	{
		$subfieldOptions = array();
			if(isset($options['childrenOptions']))
				$subfieldOptions = $options['childrenOptions'];
				

			if(!isset($subfieldOptions['div']))
				$subfieldOptions['div'] = array('class'=>'input subField');
			$subfieldOptions['subField'] = true;
			if(isset($subfieldOptions['allowMultiple']) && $subfieldOptions['allowMultiple'] == true)
			{
				$subfieldOptions['addMoreLink'] = false;
				$options['after'] = $this->addFieldLink;
			}
			if(!isset($options['after']))
			{
				$options['after'] = '';
			}

			if(!isset($options['label']))
			{
				$options['label'] = $this->label($fieldName);
			}
			$out = '';
			$children = $options['children'];
			if(!isset($options['before']))
				$options['before'] = '';
			foreach($children as $child)
			{
				$out .= $this->input($child, $subfieldOptions).':fieldSep';
			}
			$out = substr($out, 0, -9);
			$out = String::insert($out, array('fieldSep'=>'<span class="fieldSeperator"></span>'));
			$out = '<div class="input parentField">'.$options['before'].'<label>'.$options['label'].'</label>'. $out. '<div class="clear"></div>'.$options['after'].' </div>';
			return $out;
	}
	
	function allowMultiple()
	{
		$options = $this->options;
		$this->setEntity($fieldName);
		$optionsTmp = $this->__name($options);
		$options['name'] = $optionsTmp['name']."[]";
		if(!isset($options['addMoreLink']))
		{
			$options['addMoreLink'] = true; // default
		}
		
		if(isset($options['addMoreLink']) && $options['addMoreLink'] == true)
		{
			$options['after'] = $this->addFieldLink;
		}
		$this->options = $options;
	}
	*/
	
	function randomizeOptions()
	{
		$this->options['options'] = shuffle_assoc($this->options['options']);
	}
	
	function applyPosition()
	{
		$options = $this->options;
		$classNew = ' input-'.$options['position'];
		if(!isset($options['div']['class']))
		{
			$options['div']['class'] = 'input '.(isset($options['type'])?$options['type']:'select').' ';
		}
		$options['div']['class'] .=  $classNew;
		$this->options = $options;
	}
	
	function applySize()
	{
		$options = $this->options;
		$sizeClass = "size-".$options['size'];
		$options = $this->addClass($options, $sizeClass);
		unset($options['size']);
		$this->options = $options;
	}
	
	/**
	 * Additional options added for input fields:
	 * 'type':
	 * captcha (For captcha code output)
	 * editorArea (For simple HTML editor)
	 * colorPicker 
	 * 
	 * 'tooltip': To create a tooltip for the form field
	 * 'tooltipStyle': Valid only when 'tooltip' paramater is set. Default style is 'cream'
	 * 
	 *
	 * @param unknown_type $fieldName
	 * @param unknown_type $options
	 * @return unknown
	 */
	
	function input($fieldName, $options = array ()) 
	{
		$this->options = $options;
		$this->currentField = $fieldName;
		
		$this->_setDefaultOptions(); // set default options from model
		
		if(isset($this->options['buttons']))
		{
			$this->_setTemplateButtons();
		}

		if(isset($this->options['tooltip']) && $this->options['tooltip'] != null)
		{
			$this->setTooltip();
		}
		
		// transform options to add magic with special fields and special fields can over-ride output too
		$this->specialFields();
	
		// call properties object for new field properties
		App::import('Vendor', 'Cms.GigaFieldProperty');
		GigaFieldPropertyManager::manipulateFormOptions($this);
		
		if(isset($this->options['output']))
		{
			$this->options = $this->_cleanOptions($this->options);
			return $this->options['output'];
		}

		//unset unecessary $options
		if(isset($this->options['randomize']) && isset($this->options['options']) )
		{
			$this->randomizeOptions();
		}
		if(isset($this->options['position']))
		{
			$this->applyPosition();
		}
		if(isset($this->options['size']))
		{
			$this->applySize();
		}

		$this->options = $this->_cleanOptions($this->options);
		
		$options = $this->options;
		$fieldName = $this->currentField;
		if(isset($options['label']) && !empty($options['label']))
		{
			$options['label'] = __($options['label']);
		}		
		return parent :: input($fieldName, $options);
	}
	
	function _cleanOptions($options)
	{
		$cleanThese = array('allowMultiple','addMoreLink', 'group','allowmultiple','sliderOptions','columns','required','position','randomize','size','order','validation', 'triggers', 'storageModel');
		foreach($cleanThese as $key)
		{
			unset($options[$key]);
		}
		return $options;
	}
	
	function _matrix($fieldName, $type, $options)
	{
		$options['output'] =  '';
		$columns = $options['options']['columns'];
		$rows = $options['options']['rows'];

		$output = '<div class="input matrix'.ucfirst($type).'">';
		if(isset($options['before']))
		{
			$output .= $options['before'];
		}
		$tableId = str_replace('.','_',$fieldName).'_matrix_table_field'.rand(1,10);
		$label = null;
		if(isset($options['label']))
			$label = $options['label'];
		$output .= $this->label($label,null,array('for'=>''));
		$output .= '<table class="matrixTable" id="'.$tableId.'"><tr><th>&nbsp;</th>';
		if(!isset($options['label']))
			$label = $fieldName;
		else
			$label = $options['label'];
		
		// build table header
		foreach($columns as $column)
		{
			$output .= "<th>".$column."</th>";
		}
		$output .= "</tr>";
		foreach($rows as $key=>$row)
		{
			$output .= "<tr>";
			$output .= "<td>".$row."</td>";
			
			$inputOptions = array();
			$inputOptions['label'] = true;
			$inputOptions['legend'] = false;
			$inputOptions['div'] = false;
			$inputOptions['type'] = $type;
			$inputOptions['separator'] = "</td><td>";
			$inputOptions['options'] = $columns;
			$inputOptions['error'] = false;
			if($type=='checkbox')
			{
				$inputOptions['type'] = 'checkboxGroup';
				$this->disableDiv = true; // hack to disable div-wrap on checkboxes
			}
			$output .= "<td>".$this->input($fieldName.'.'.$key, $inputOptions)."</td>";
			$output .= "</tr>";
		}
		$output .= '</table>';
		if(isset($options['other_field']))
			$output .= $this->_otherField($fieldName,$options['other_field'],true,true);
		if(isset($options['after']))
			$output  .= $options['after'];
		$output .='</div>';
		$options['output'] = $output;
		$options['output'] .= $this->error($fieldName);
		if(isset($options['one_per_column']) && $options['one_per_column']==1)
		{
			$options['output'] .= <<< END
				<script type="text/javascript">	
				$(document).ready(function(){
						\$('.matrixTable#$tableId').find('input[type!="hidden"]').click(function(){
						index = \$(this).parent().parent().children().index(\$(this).parent())
						\$(this).parent().parent().siblings().find('td:eq('+index+') > input[type!="hidden"]').attr('checked',false);
						})
					});
				</script> 
END;
		}
		return $options;
	}
	function _rankOrder($fieldName, $options)
	{
		$selectOptions = range(1,count($options['options']));
		if(isset($options['randomize']) && $options['randomize']==1 )
		{
			//$selectOptions = shuffle_assoc($selectOptions);
			$options['options'] = shuffle_assoc($options['options']);
		}
		$inputOptions['error'] = false;
		$inputOptions['options'] = $selectOptions;
		$inputOptions['type'] = 'select';
		$inputOptions['label'] = false;
		$inputOptions['empty'] = '-';
		$inputOptions['div'] = false;
		if(!isset($options['before']))
			$options['before'] = '';
		if(!isset($options['label']))
			$label = $fieldName;
		else
			$label = $options['label'];
		$output = '<div class="input rankOrder">'.$options['before'].$this->label($label,null,array('for'=>'')).'<table class="rankOrder"><tr><th>&nbsp;</th><th></th></tr>';
		foreach($options['options'] as $key => $row)
		{
			$output .= '<tr>';
			$output   .= '<td>'.$row.'</td>';
			$subFieldName = $fieldName.'.'.$key;
			$output .= '<td>'.$this->input($subFieldName,$inputOptions).'</td>';
			$output .= '</tr>';
		}
		$output .= '</table></div>';
		$options['output'] = $output;
		$options['output'] .= $this->error($fieldName);
		return $options;
	}
	
	function specialFields() 
	{
		$fieldName = $this->currentField;
		$options = $this->options;
		
		if (!isset ($options['type'])) {
			return $options;
		}
		$options = $this->addClass($options, $options['type']);
		switch ($options['type']) {
			case 'matrixRadio':
				$options = $this->_matrix($fieldName, 'radio', $options);
				break;
			case 'matrixCheckbox':
				$options = $this->_matrix($fieldName, 'checkbox', $options);
				break;
			case 'matrixScale':
				$cols = array();
				$cols[$options['left_size']]  = $options['left_value'].'<br />'.$options['left_size'];
				for($i = $options['left_size']+1 ; $i <  $options['right_size'] ; $i++)
				{
					$cols[$i] = ' <br />'.$i;
				}
				$cols[$options['right_size']] = $options['right_value'].'<br />'.$options['right_size'];
				$options['options']['columns'] = $cols;
				unset($cols);
				$options = $this->_matrix($fieldName, $options['scale_type'], $options);
				break;
			case 'rankOrder':
				$options = $this->_rankOrder($fieldName,  $options);
				break;
			case 'countrySuggestor':
				$options['options'] = Utility::getCountries();
				$options['type']='select';
				break;
			case 'autocomplete' :
				$options = $this->typeAutocomplete($fieldName,$options);
				$options['type']='text';
				break;
			case 'rating':
				$options = $this->{$this->ratingFn}($fieldName,$options);
				break;
			case 'checkboxGroup' :
			case 'multipleCheckbox' :
				$options['multiple'] = 'checkbox';
				unset ($options['type']);
				break;
			case 'multipleSelect' :
				$options['multiple'] = true;
				unset ($options['type']);
				//prd($options);
				break;							
			case 'captcha' :
				$options = $this->captcha();
				break;
			case 'editor' :
				$domClassName = "editorArea";
				// load editor helper 
				App :: import('Helper', 'Editor.Editor');
				if(!isset($options['id']))
				{
					$options['id'] = $this->domId($fieldName);
				}
				$editor = new EditorHelper();
				$editorOptions = isset($options['editorOptions']) ? $options['editorOptions'] : array();
				$editorOptions['id'] = $options['id'];
				$editor->outputJS($domClassName, $editorOptions);

				if (isset ($options['class'])) {
					$options['class'] .= ' ' . $domClassName;
				} else {
					$options['class'] = $domClassName;
				}
				$options['type'] = 'textarea';
				break;
			case 'colorPicker' :
				$options['type'] = "text";
				$randomClass = "colorpickerField_" . mt_rand();
				if (isset ($options['class'])) {
					$options['class'] .= ' cpInput ' . $randomClass;
				} else {
					$options['class'] = "cpInput " . $randomClass;
				}

				$cpOptions = array ();
				$cpOptions['color'] = "FFF";
				$cpOptions['colorSelectId'] = "colorSelector_" . mt_rand();

				if (isset ($options['value']) && $options['value'] != '') {
					$cpOptions['color'] = $options['value'];
				}
				$this->Html->css('/cms/css/colorpicker.css',null,array(),false);
				$this->Javascript->link('/cms/js/colorpicker.js',false);
		
				$colorSelector = '<div class="colorSelectorDiv" id="' . $cpOptions['colorSelectId'] . '"><div style="background-color: #' . $cpOptions['color'] . '"></div></div>';
				//$cpCode = '<script>$(document).ready(function() { $("input.colorpickerField").ColorPicker({color: "fff", flat: true}); });</script>';
				$onChange = null;
				if(isset($options['onchange']))
				{
					$onChange = $options['onchange'];
				}
				echo "<script>	
									$(document).ready(function() {
										selectedColor = $('input." . $randomClass . "').val();
										$('#" . $cpOptions['colorSelectId'] . " div').css('backgroundColor', '#' + selectedColor);
										$('#" . $cpOptions['colorSelectId'] . "').ColorPicker({
											color: '#'+selectedColor,
											onShow: function (colpkr) {
												$(colpkr).fadeIn(500);
												return false;
											},
											onHide: function (colpkr) {
												$(colpkr).fadeOut(500);
												$onChange
												return false;
											},
											onChange: function (hsb, hex, rgb) {
												$('#" . $cpOptions['colorSelectId'] . " div').css('backgroundColor', '#' + hex);
												$('input." . $randomClass . "').val(hex);
												
											}
										}); });
									</script>
									";

				$options['after'] = $colorSelector;
				//$options['style'] = "display: hidden;";
				//$out .= $cssJs;

				break;

			case 'slider' :
				// input type sliders
				if (!isset ($options['id'])) {
					$options['id'] = $this->domId($fieldName);
				}

				App :: import('Helper', 'Cms.Slider');
				$slider = new SliderHelper();

				if (!isset ($options['sliderOptions'])) {
					$options['sliderOptions'] = array ();
				}

				$sliderOutput = $slider->generateOutput($options, $options['sliderOptions']);
				unset ($options['sliderOptions']);
				$options = $sliderOutput['options'];
				$options['after'] = $sliderOutput['output'];

				break;
			
			case 'datePicker':
				$this->addJUI();
				if (!isset ($options['id'])) {
					$options['id'] = $this->domId($fieldName);
				}
				if(!isset($options['datePickerOptions']))
				{
					$options['datePickerOptions'] = array();
				}
				if(isset($options['date_format']))
				{
					$options['datePickerOptions']['dateFormat'] = $options['date_format'];
					unset($options['date_format']);
				}
				$defaultOptions = array('dateFormat'=>"yy-mm-dd",'changeYear'=>true,'yearRange'=>(intval(date('Y')-15).":".intval(date('Y')+5)));
				$defaultOptions = am($defaultOptions,(array)cr('Cms.Datepicker.options'));
				$options['datePickerOptions'] = am($defaultOptions,$options['datePickerOptions']);
				if(isset($options['minYear']) || isset($options['maxYear']))
				{
					if(!isset($options['minYear']) || empty($options['minYear']))
					{
						$options['minYear'] = date('Y');						
					}
					if(!isset($options['maxYear']) || empty($options['maxYear']))
					{
						$options['maxYear'] = date('Y');
					}
					$options['datePickerOptions']['changeYear'] = true; 
					$options['datePickerOptions']['yearRange'] = $options['minYear'].':+'.$options['maxYear'];
				}
								
				if (!isset ($options['datePickerOptions'])) {
					$jsonVars = '';
				} else {
					$this->initHelper('Javascript');
					$jsonVars = $this->Javascript->Object($options['datePickerOptions']);
				}
				//prd($jsonVars );
				unset ($options['datePickerOptions']);
				$options['type'] = 'text';
				$options['after'] = '<script>$(function() {	$("#' . $options['id'] . '").datepicker(' . $jsonVars . '); });</script>';
				break;
				
			case 'starRating':
				// add star rating code here
				break;	
			case 'radio':
				if(!isset($options['legend']) && isset($options['label']))
					$options['legend'] =  $options['label'];
				break;
			case 'multipleInput':
				$options['children'] = $options['options'];
				$options['childrenOptions']['type'] = 'text';
				break;
			case 'number':
			case 'email':
			case 'url':
				$options['type'] = 'text';
             break;
			case 'currency':
				$options['type'] = "select";
				$options['options']  = cri('Cms.Currency')->getDisplayCurrecies();
				if(!isset($options['value']) || !$this->data)
				{
					$options['value'] = cri('Cms.Currency')->getClientCurrency(); 
				}
				break;
		}
		
		if(!isset($options['type']))
		{
			$options['type'] = null; // @todo Remove this hack
		}
		$fieldTypeObj = Utility::getFieldObject($options['type']);
		if($fieldTypeObj)
		{
			$options = $fieldTypeObj->getFormOptions($this, $fieldName, $options);
		}
		
		$this->options = $options;
	}

	
	/**
	 * Internal function to generate captcha field options
	 * @return unknown_type
	 */
	function captcha()
	{
		$options = $this->options;
		if (!isset ($options['label'])) {
			$options['label'] = "Captcha code";
		}
		if(cr('Cms.recaptcha.status'))
		{
			App::import('Vendor', 'Cms.recaptchalib');
			$options['output'] = recaptcha_get_html(cr('Cms.recaptcha.public_key'), '');
		}
		else
		{
			//$options['before'] = '<img src="' . $this->Html->url('/cms/captcha/image/220?cachebust='.time()) . '">';
			//T.Trung
			$options['after'] = '<img src="' . $this->Html->url('/cms/captcha/image/220?cachebust='.time()) . '">';
			//T.Trung end
			if(!isset($options['div']))
				$options['div'] = array();
			$options['div']=  $this->addClass($options['div'], 'required input text');	
		}

		unset($options['type']);
		return $options;
	}
	
	/**
	 * Get field type from the associated model
	 * @param $fieldName
	 * @param $options
	 * @return unknown_type
	 */
	/**
	 * Convenience function for EAV Input groups
	 */

	function inputs($fields = null, $blacklist = null, $group = null) 
	{
		$model = & ClassRegistry :: getObject($this->model());
		
		if(isset($group) && $group!=null)
		{
			$model = & ClassRegistry :: getObject($this->model());
			if(is_array($grpFields = $model->getFields('group',$group)) && !empty($grpFields))
			{
				if(!empty($fields))
					$fields = am($fields, $grpFields);
				else
					$fields = $grpFields;
			}
			elseif(empty($grpFields))
			{
				return;
			}
		}
	
		return parent :: inputs($fields, $blacklist);
	}
	
	function elements($elements,$showQuestionNumber=false,$numberStart=1)
	{
		$out = '';
		foreach($elements as $element)
		{
			if($element['type']=='input')
			{
				$option = array();
				if($showQuestionNumber==true)
					$option['before'] = '<h4 class="field-order">'.$numberStart.'.</h4>';
				$numberStart++;
				$out .= $this->input($element['name'],$option);
			}
			else
			{
				$out .= $this->element($element['type'], $element['value']);
			}
		}
		return $out;
	}
	
	function element($type, $value)
	{
		if($type=='para' || $type == 'element_text')
			return $value;
		if($type=='sectionBreak' || $type =='element_sectionBreak')
			return "<hr />";
		if($type=='image' || $type =='element_image')
		{
			if($value!= null || strlen($value) > 1)
				return $this->Html->image('/uploads/'.$value);
		}
		if($type=='element_document'|| $type=='document')
		{
			return $this->Html->link('Click to view: '.$value, '/uploads/'.$value);
		}						
	}
		

	function typeAutocomplete($field,$options)
	{
		$typeOptions = array('url'=>'','minChars'=>'1','lineSeparator'=>'^','cacheLength'=>0);
		$typeOptions = am($typeOptions,array_intersect_key($options,$typeOptions));
		if($typeOptions['url']=='')
			return;
		$typeOptions['url']  = $this->Html->url($options['url']);
		if(!isset($options['id']))
			$options['id'] = $this->domId($field);
		$this->initHelper('Cms.Autocomplete');
		$out = $this->Autocomplete->generateOutput('#'.$options['id'],$typeOptions);
		$options = array_diff_key($options,$typeOptions);
		return $options ;

	}
	function typeRating($field,$options)
	{
		if(!isset($this->Rating) || !is_object($this->Rating))
		{
			$this->initHelper('Rating.Rating');
			$this->Rating->Html = $this->Html;
			$this->Rating->Javascript = $this->Javascript;
			$this->Rating->Form = $this;
		}
		$options['output'] = $this->Rating->star($field,$options);
		return $options;
	}
	
	// function for supporting older versions
	function typeRating_legacy($field,$options)
	{
		$viewObj = ClassRegistry::init('View');
		$typeOptions = array('rating'=>5,'onchange'=>'','rate_revert'=>true);
		$typeOptions =  am($typeOptions,array_intersect_key($options,$typeOptions));
		if(!isset($options['id']))
			$options['id'] = $this->domId($field);
		
		$out = "";
		$out .= $viewObj->element('form_rating',array('plugin'=>'cms','field'=>$field,'options'=>$typeOptions,'fieldId' => $options['id']));
		$options['after'] = $out ;
		unset($options['rating']);
		unset($options['onchange']);
		$options['type'] = 'text';
		$options['style'] = 'display:none';
		return $options;
	}

	function select($fieldName, $options = array(), $selected = null, $attributes = array(), $showEmpty = '') 
	{
		$select = array();

		// @todo fix hack
		if(isset($this->defaultEmpty) &&  !array_key_exists('multiple', $attributes))
			$showEmpty = $this->defaultEmpty;
		$showParents = false;
		$escapeOptions = true;
		$style = null;
		$tag = null;
		//Hack For other Field
		if(isset($attributes['other_field']))
		{
			$otherField = $attributes['other_field'];
			unset($attributes['other_field']);
		}
		if (isset($attributes['escape'])) {
			$escapeOptions = $attributes['escape'];
			unset($attributes['escape']);
		}
		$attributes = $this->_initInputField($fieldName, array_merge(
			(array)$attributes, array('secure' => false)
		));

		if (is_string($options) && isset($this->__options[$options])) {
			$options = $this->__generateOptions($options);
		} elseif (!is_array($options)) {
			$options = array();
		}
		if (isset($attributes['type'])) {
			unset($attributes['type']);
		}
		if (in_array('showParents', $attributes)) {
			$showParents = true;
			unset($attributes['showParents']);
		}

		if (!isset($selected)) {
			$selected = $attributes['value'];
		}

		if (isset($attributes) && array_key_exists('multiple', $attributes)) {
			$style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
			$template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
			$tag = $this->Html->tags[$template];
			$select[] = $this->hidden(null, array('value' => '', 'id' => null, 'secure' => false));
		} else {
			$tag = $this->Html->tags['selectstart'];
		}

		if (!empty($tag) || isset($template)) {
			$this->__secure();
			$select[] = sprintf($tag, $attributes['name'], $this->_parseAttributes(
				$attributes, array('name', 'value'))
			);
		}
		$emptyMulti = (
			$showEmpty !== null && $showEmpty !== false && !(
				empty($showEmpty) && (isset($attributes) &&
				array_key_exists('multiple', $attributes))
			)
		);

		if ($emptyMulti) {
			$showEmpty = ($showEmpty === true) ? '' : $showEmpty;
			$options = array_reverse($options, true);
			$options[''] = $showEmpty;
			$options = array_reverse($options, true);
		}
		if(isset($otherField) && is_array($selected))
		{
			if(isset($selected['other']))
				unset($selected['other']);
			if(isset($selected['other_check']))
				unset($selected['other_check']);
		}
		$inputs = $this->__selectOptions(
			array_reverse($options, true),
			$selected,
			array(),
			$showParents,
			array('escape' => $escapeOptions, 'style' => $style)
		);
		$inbetween = null;
		if (isset($attributes['separator'])) {
			$inbetween = $attributes['separator'];
			unset($attributes['separator']);
		}		

		$inputLength = count($inputs);
		$lastkey = end(array_keys($inputs));
		foreach($inputs as $key => $tmpField)
		{
			if($key != $lastkey)
				$inputs[$key] .= $inbetween;
		}
		$select = array_merge($select, $inputs);
		$template = ($style == 'checkbox') ? 'checkboxmultipleend' : 'selectend';
		$select[] = $this->Html->tags[$template];
		$deep = array_key_exists('multiple', $attributes) ==true? 1 : 0;

		if(isset($otherField))
		{
			$select[] = $this->_otherField($fieldName,$otherField,$deep);
		}
		$classClear = '';
		if($template == 'checkboxmultipleend')
		{
			$classClear = '<div class="clear"></div>';
		}
		return $this->output(implode("\n", $select)).$classClear;
	}
			
/**
 * Returns an array of formatted OPTION/OPTGROUP elements
 * @access private
 * @return array
 */
	function __selectOptions($elements = array(), $selected = null, $parents = array(), $showParents = null, $attributes = array()) {
		$select = array();
		$attributes = array_merge(array('escape' => true, 'style' => null), $attributes);
		$selectedIsEmpty = ($selected === '' || $selected === null);
		$selectedIsArray = is_array($selected);

		foreach ($elements as $name => $title) {
			$htmlOptions = array();
			if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) {
				if (!empty($name)) {
					if ($attributes['style'] === 'checkbox') {
						$select[] = $this->Html->tags['fieldsetend'];
					} else {
						$select[] = $this->Html->tags['optiongroupend'];
					}
					$parents[] = $name;
				}
				$select = array_merge($select, $this->__selectOptions(
					$title, $selected, $parents, $showParents, $attributes
				));

				if (!empty($name)) {
					if ($attributes['style'] === 'checkbox') {
						$select[] = sprintf($this->Html->tags['fieldsetstart'], $name);
					} else {
						$select[] = sprintf($this->Html->tags['optiongroup'], $name, '');
					}
				}
				$name = null;
			} elseif (is_array($title)) {
				$htmlOptions = $title;
				$name = $title['value'];
				$title = $title['name'];
				unset($htmlOptions['name'], $htmlOptions['value']);
			}

			if ($name !== null) {
				if ((!$selectedIsEmpty && $selected == $name) || ($selectedIsArray && in_array($name, $selected))) {
					if ($attributes['style'] === 'checkbox') {
						$htmlOptions['checked'] = true;
					} else {
						$htmlOptions['selected'] = 'selected';
					}
				}

				if ($showParents || (!in_array($title, $parents))) {
					$title = ($attributes['escape']) ? h($title) : $title;

					if ($attributes['style'] === 'checkbox') {
						$htmlOptions['value'] = $name;

						$tagName = Inflector::camelize(
							$this->model() . '_' . $this->field().'_'.Inflector::underscore($name)
						);
						$htmlOptions['id'] = $tagName;
						$label = array('for' => $tagName);

						if (isset($htmlOptions['checked']) && $htmlOptions['checked'] === true) {
							$label['class'] = 'selected';
						}

						list($name) = array_values($this->__name());

						if (empty($attributes['class'])) {
							$attributes['class'] = 'checkbox';
						}
						$label = $this->label(null, $title, $label);
						$item = sprintf(
							$this->Html->tags['checkboxmultiple'], $name,
							$this->_parseAttributes($htmlOptions)
						);
						
						if($this->disableDiv==true)
						{
							$select[] = $item . $label;
						} else 
						{
							$select[] = $this->Html->div($attributes['class'], $item . $label);
						}
					} else {
						$select[] = sprintf(
							$this->Html->tags['selectoption'],
							$name, $this->_parseAttributes($htmlOptions), $title
						);
					}
				}
			}
		}
		return array_reverse($select, true);
	}

	function _otherField($fieldName,$options='',$deep=false,$ishidden=false)
	{
		$js = <<< END
			<script type="text/javascript">
			function resetOther(dom,id,deep)
			{
				if(deep==1)
				{
					var neighbours = \$(dom).parent().siblings().find('input,select');
				}
				else
					var neighbours = \$(dom).parent().siblings('input,select');
				if(\$(dom).attr('checked')==true)
				{
					\$('#'+id).attr('disabled',false);
					neighbours.attr('disabled',true);
				}
				else
				{
					neighbours.attr('disabled',false);
					\$('#'+id).attr('disabled',true);
				}
			}
			</script>
END;
		ClassRegistry::getObject('View')->addScript('OTHER_FIELD_JS',$js);
		if(is_array($options))
		{
			extract($options);
		}else
			$label = $options;
		$fieldNameForText = $fieldName.'.other';
		$id = $this->domId($fieldNameForText);
		$tickBoxId = $this->domId($fieldName.'.other_check');
		$tickBox = $this->__otherFieldTickbox($fieldName.'.other_check',array('onchange'=>'resetOther(this,\''.$id.'\','.(int)$deep.')'),$disabled);
		$this->addJqBlock('resetOther($("#'.$tickBoxId.'"),\''.$id.'\','.(int)$deep.')');
		$options = array('label'=>false,'id'=>$id,'disabled'=>$disabled);
		if($disabled==true)
			$options['value'] = ''; 
		if($ishidden==false)
			$label = $label.$this->text($fieldNameForText,$options);
		else
			$label = $label.$this->hidden($fieldNameForText,am($options,array('value'=>1)));
		$out =  $tickBox.$label;
		$out = '<div class="other">'.$out.'</div>';
		return $out;
	}

	function __otherFieldTickbox($fieldName,$options,&$disabled)
	{
		$options = $this->_initInputField($fieldName, $options);
		$options['value'] =1;
		$value = $this->setEntity($fieldName);
		$modelName = $this->model();
		$parentField =  $this->field();
		$data = ClassRegistry::getObject('view')->data;
		$value = null;
		if(isset($data[$modelName][$parentField]) && is_array($data[$modelName][$parentField]) && is_array($data[$modelName][$parentField]) &&  isset($data[$modelName][$parentField]['other_check']) && $data[$modelName][$parentField]['other_check'] ==1 )
		{
			$value = 1;
		}
		if($value==null)
		{
				$options['checked'] = false;
				$disabled = true;
		}
		else
		{	
			$options['checked'] = true;
			$disabled = false;
		}
		return $this->output(sprintf($this->Html->tags['checkbox'],$options['name'],$this->_parseAttributes($options, array('name'), null, '')));
	}


	
	/**
 * READ THIS :: Remove this function from here for projects other than websurveys , implements other fiele concept
 * 
 * Creates a set of radio widgets.
 * 
 * Attributes:
 *
 * - 'separator' - define the string in between the radio buttons
 * - 'legend' - control whether or not the widget set has a fieldset & legend
 * - 'value' - indicate a value that is should be checked
 * - 'label' - boolean to indicate whether or not labels for widgets show be displayed
 *
 * @param string $fieldName Name of a field, like this "Modelname.fieldname"
 * @param array $options Radio button options array.
 * @param array $attributes Array of HTML attributes.
 * @return string
 */
	function radio($fieldName, $options = array(), $attributes = array()) {
		$attributes = $this->_initInputField($fieldName, $attributes);
		if(isset($attributes['other_field']))
		{
			$otherField = $attributes['other_field'];
			unset($attributes['other_field']);
		}
		$legend = false;
		$afterLabel = null;
		if(isset($attributes['afterLabel']))
		{
			$afterLabel = $attributes['afterLabel'];
			unset($attributes['afterLabel']);
		}
		if (isset($attributes['legend'])) {
			$legend = $attributes['legend'];
			unset($attributes['legend']);
		} elseif (count($options) > 1) {
			$legend = __(Inflector::humanize($this->field()), true);
		}
		$legend = __($legend);
		$label = true;

		if (isset($attributes['label'])) {
			$label = $attributes['label'];
			unset($attributes['label']);
		}
		$inbetween = null;
		if (isset($attributes['separator'])) {
			$inbetween = $attributes['separator'];
			unset($attributes['separator']);
		}

		if (isset($attributes['value'])) {
			$value = $attributes['value'];
		} else {
			$value =  $this->value($fieldName);
		}
		//this is to prevent null value to acts as zero value
		$out = array();

		foreach ($options as $optValue => $optTitle) {
			$optionsHere = array('value' => $optValue);

			if (isset($value) && $value!='' && $optValue == $value) {
				$optionsHere['checked'] = 'checked';
			}
			$parsedOptions = $this->_parseAttributes(
				array_merge($attributes, $optionsHere),
				array('name', 'type', 'id'), '', ' '
			);
			$tagName = Inflector::camelize(
				$attributes['id'] . '_' . Inflector::underscore($optValue)
			);

			if ($label) {
				$optTitle =  sprintf($this->Html->tags['label'], $tagName, null, __($optTitle));
			}
			$out[] =  sprintf(
				$this->Html->tags['radio'], $attributes['name'],
				$tagName, $parsedOptions, $optTitle
			);
		}
		$hidden = null;

		if (!isset($value) || $value === '') {
			$hidden = $this->hidden($fieldName, array(
				'id' => $attributes['id'] . '_', 'value' => '', 'name' => $attributes['name']
			));
		}
		$out = $hidden . join($inbetween, $out);
		if(isset($otherField))
		{
			$out .= $this->_otherField($fieldName,$otherField); 
		}
		if ($legend) {
			$out = sprintf(
				$this->Html->tags['fieldset'], '',
				sprintf($this->Html->tags['legend'], $legend,$afterLabel) . $out
			);
		}
		return $this->output($out);
	}
	


	function setTooltip()
	{
		$fieldName = $this->currentField;
		$options = $this->options;
		
		if(!isset($this->ToolTip))
		{
			$this->initHelper('Cms.Tooltip');
		}
		if(!isset($this->toolTipType) || $this->toolTipType =='qtip')
		{
			$this->setEntity($fieldName);
			$options = $this->domId($options);
			$tooltipOptions = array();
			$defaultTooltipOtions = array();
			if(is_array($options['tooltip']))
			{
				$tooltiptext = $options['tooltip']['content'];
				unset($options['tooltip']['content']);
				$tooltipOptions =  $options['tooltip'];
				$defaultTooltipOtions  = $tooltipOptions;
			}else
			{
				$tooltiptext =$options['tooltip'];
			}
			if(isset($options['type']))
			{
				switch($options['type'])
				{
					case 'radio':
						$tooltipOptions['show'] = array('when'=>array('event'=>"mouseover"));
						$tooltipOptions['hide'] = array('when'=>array('event'=>"mouseout"));
						$tooltipOptions['selector'] = '$("#'.$options['id'].'_").parent()';
						break;
					case 'select':
						$tooltipOptions['style'] = array('tip'=>"leftMiddle");
						$tooltipOptions['position']['corner'] = array('target'=>'rightMiddle','tooltip'=>"leftMiddle");
						break;
					case 'rating':
						$tooltipOptions['show'] = array('when'=>array('event'=>"mouseover"));
						$tooltipOptions['hide'] = array('when'=>array('event'=>"mouseout"));
						$tooltipOptions['style'] = array('tip'=>"leftMiddle");
						$tooltipOptions['position']['corner'] = array('target'=>'rightMiddle','tooltip'=>"topMiddle");
					break;
					case 'multipleCheckbox':
						$model = $this->_getCurrentModel();
						$tooltipOptions['show'] = array('when'=>array('event'=>"mouseover"));
						$tooltipOptions['hide'] = array('when'=>array('event'=>"mouseout"));
						$tooltipOptions['selector'] = '$(\'[name="data['.$model->alias.']['.$fieldName.']"]\').parent()';
						$tooltipOptions['style'] = array('tip'=>"bottomLeft");
						$tooltipOptions['position']['corner'] = array('target'=>'topLeft','tooltip'=>"bottomLeft");
					break;
				}
			}
			$tooltipOptions = Set::merge($tooltipOptions,$defaultTooltipOtions);
			$tooltipSelector = '#'.$options['id'];
			if(is_array($tooltipOptions) && isset($tooltipOptions['selector']))
			{
				$tooltipSelector = $tooltipOptions['selector'];
				unset($tooltipOptions['selector']);
			}
			$this->Tooltip->addQtipTooltip($tooltipSelector,$tooltiptext,$tooltipOptions);
		}
		else if( $this->toolTipType =='after' )
		{
			if(!isset($options['label']))
				$options['label'] = $this->label($fieldName);
			$options['label'] .= $this->Html->tag('div',$options['tooltip'],array('class'=>'tooltip'),false);
		}
		else if($this->toolTipType =='helpBox')
		{
			$options['afterLabel'] = $this->Tooltip->helpTextBox($options['tooltip']);
		}
		$options['tooltip'] = false;
		$this->options = $options;
	}
	
	/**
	 * This returns $options directly to input
	 */
	function _setTemplateButtons()
	{
		extract($this->options['buttons']);
		$domId = $this->domId($this->currentField);
		if(!isset($fields))
		{
			$fields = array();
		}
		
		$this->options['after'] = $this->variableButtons($plugin, $model, $fields, $domId);
	}
	
	function variableButtons($plugin, $model, $fields, $domId)
	{
		$output = '';
		if(empty($fields))
		{
			$fields = $this->getModel($plugin, $model)->getFields();
		}
		foreach($fields as $field)
		{
			$label = $this->getModel($plugin, $model)->getFieldProperties($field, 'label');
			if(!$label)
			{
				$label = Inflector::humanize($field);
			}
			$output .= $this->Html->button(__($label), null, array('onclick'=>'insertAtCursor("'.$domId.'", "[['.$field.']]"); return false;'));
		}
		return $output;
	}
	
	function buttonSet($buttons)
	{
		$output = '<div class="buttonSet">';
		foreach($buttons as $caption => $options)
		{
			if(!is_array($options))
			{
				$caption = $options;
				$options = array();
			}
			$options['name'] = 'button';
			$options['value'] = strtolower($caption);
			$output .= $this->submit($caption, $options);
		}
		$output .= '</div>';
		return $output;
	}
}

?>